-
Notifications
You must be signed in to change notification settings - Fork 8.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Saved Objects] Update the migrationVersion
property to hold a plain string value
#150075
Conversation
migrationVersion
property to hold a plain string value
91bd29b
to
68ddd12
Compare
…nstead of deprecated `migrationVersion`
68ddd12
to
45c34f6
Compare
673b578
to
cb5b1e4
Compare
4e3aa3a
to
89301b2
Compare
Pinging @elastic/kibana-core (Team:Core) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see SharedUX is tagged for review because of src/plugins/home/server/services/sample_data
, changes in sample LGTM.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
kibana-gis changes LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ML changes LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just did a first pass and will go through the code in more detail again.
We're technically making a breaking change to the API by not responding with migrationVersion
anymore. It's hard to know if external integratinos ever rely on this field but we should rather be safe than sorry.
I think we can add a very light-weight compatibility layer by basically applying the transformation from packages/core/saved-objects/core-saved-objects-migration-server-internal/src/document_migrator/migrations/transform_migration_version.ts
(and it's opposite) at the API layer. That way the API stays 100% the same.
That means we can remove migrationVersion
in all the rest of our code like the documentMigrator and saved objects typescript APIs as well.
...re/saved-objects/core-saved-objects-migration-server-internal/src/document_migrator/types.ts
Outdated
Show resolved
Hide resolved
...re/saved-objects/core-saved-objects-migration-server-internal/src/document_migrator/types.ts
Show resolved
Hide resolved
...re/saved-objects/core-saved-objects-migration-server-internal/src/document_migrator/types.ts
Outdated
Show resolved
Hide resolved
@@ -159,6 +159,9 @@ export function getBaseMappings(): IndexMapping { | |||
coreMigrationVersion: { | |||
type: 'keyword', | |||
}, | |||
typeMigrationVersion: { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can't comment at the right place, but we should remove the mapping for migrationVersion
on line 124
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We cannot remove that yet as we are updating mappings when there are still documents with the old migrationVersion
properties. That happens before we apply core migrations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removing a field will mean the migration algorithm doesn't think we've made an incompatible mappings change, so it would re-use the index instead of creating a new one. But mappings updates are commutative, so even if we update the mappings without migrationVersion
ES will still keep it on existing indices.
Whenever we create a new index we should run the OUTDATED_DOCUMENTS_TRANSFORM* steps before we apply the final mappings to the index.
So I can't really imagine where this would fail?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So I think this is because we don't check for coreMigrationVersion in the outdatedDocumentsQuery. So unless:
a) there's incompatible mappings and we reindex all documents
b) all saved object types have a new typeMigrationVersion (unlikely)
Some documents will be the old coreMigrationVersion and require the migrationVersion mapping.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall great job, this was some massive work.
Regarding the HTTP APIs, even if I personally think that it would probably be fine for 99% of the usages, I'm forced to agree with @rudolf on the fact that we should probably be cautious, and try to preserve the existing shape for responses when possible.
My other comments and remarks:
packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/internal_utils.ts
Show resolved
Hide resolved
packages/core/saved-objects/core-saved-objects-api-server-internal/src/lib/repository.test.ts
Outdated
Show resolved
Hide resolved
...(migrationVersion && { migrationVersion }), | ||
...(coreMigrationVersion && { coreMigrationVersion }), | ||
...(typeMigrationVersion != null ? { typeMigrationVersion } : {}), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NIT: There's a subtle difference of behavior between typeMigrationVersion
and the other attributes here (X && { X }
vs X != null ? { X } : {}
) . Not saying that one is better than the other, but isn't that a risk somehow to have this specific prop handled differently here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's good notice. That's done so to keep backward compatibility -- previously, we used migrationVersion: {}
to trigger migrations, but now an empty string does that trick. In order to keep the value, we are using this ternary operator.
...cts/core-saved-objects-import-export-server-internal/src/import/lib/collect_saved_objects.ts
Show resolved
Hide resolved
...core/saved-objects/core-saved-objects-migration-server-internal/src/core/migrate_raw_docs.ts
Show resolved
Hide resolved
...ects/core-saved-objects-migration-server-internal/src/document_migrator/document_migrator.ts
Outdated
Show resolved
Hide resolved
private convertNamespaceTypes: boolean | ||
) {} | ||
|
||
protected *getPipeline(): Generator<Transform> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was going to say that I wasn't sure a generator was really necessary given that the migration workstream is predictable, but actually because of the edge case of type switch, it's not 😄
As a side note for later me/us, we will need to break/remove that type switching capability for ZDT
must: [ | ||
{ term: { type } }, | ||
{ | ||
bool: { | ||
should: [ | ||
{ | ||
bool: { | ||
must: { exists: { field: 'migrationVersion' } }, | ||
must_not: { term: { [`migrationVersion.${type}`]: latestVersion } }, | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Backlinking #153031, because the equivalent query for the zdt
algorithm will have to be adapted too.
@@ -118,7 +118,7 @@ describe('migration v2', () => { | |||
await root.preboot(); | |||
await root.setup(); | |||
await expect(root.start()).rejects.toMatchInlineSnapshot( | |||
`[Error: Unable to complete saved object migrations for the [.kibana] index: The document with _id "canvas-workpad-template:workpad-template-061d7868-2b4e-4dc8-8bf7-3772b52926e5" is 1715272 bytes which exceeds the configured maximum batch size of 1015275 bytes. To proceed, please increase the 'migrations.maxBatchSizeBytes' Kibana configuration option and ensure that the Elasticsearch 'http.max_content_length' configuration option is set to an equal or larger value.]` | |||
`[Error: Unable to complete saved object migrations for the [.kibana] index: The document with _id "canvas-workpad-template:workpad-template-061d7868-2b4e-4dc8-8bf7-3772b52926e5" is 1715248 bytes which exceeds the configured maximum batch size of 1015275 bytes. To proceed, please increase the 'migrations.maxBatchSizeBytes' Kibana configuration option and ensure that the Elasticsearch 'http.max_content_length' configuration option is set to an equal or larger value.]` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NIT: Outside of the scope of this PR but we should probably adapt those tests to not assert on the exact size of the documents 🙈
typeMigrationVersion: { | ||
type: 'version', | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question: given we will be converting it to typeMigrationVersion
during the migration, do we need to keep the migrationVersion
field in our schema?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, we still need it to provide compatible mappings.
💚 Build Succeeded
Metrics [docs]Public APIs missing comments
Page load bundle
Saved Objects .kibana field count
Unknown metric groupsAPI count
ESLint disabled line counts
References to deprecated APIs
Total ESLint disabled count
History
To update your PR or re-run it, just comment with: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
In addition to the endpoints BWC, we probably want to open a follow-up issue to talk about whether we should change the migration algorithm(s) to forcefully migrate all documents when coreMigrationVersion
changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will create an issue for fixing API compatibility and migrationVersion mappings in a separate PR
…n string value (elastic#150075) * Update document migrator to rely on `typeMigrationVersion` instead of `migrationVersion`. * Refactor document migrator to extract migration pipeline logic. * Add `core` migration type.
Summary
Resolves #70815.
Checklist
For maintainers